#include "EventEngine/IActor.h"

namespace NTrader
{

IActor::IActor(size_t bufsize)
	: __waitStrategy()
	, __claimStrategy(bufsize,__waitStrategy)
	, __consumed(__waitStrategy, bufsize-1)
	, __buffer(bufsize)
	, _status(WAITING)
	, __nextToRead(0)
{
	_inerHandle = fastdelegate::MakeDelegate(this, &IActor::EventHandler);
	__claimStrategy.add_claim_barrier(__consumed);
}

void IActor::SetStatus(int s)
{
	_status.store(s,std::memory_order_release);
}

int IActor::GetStatus()
{
	return _status.load(std::memory_order_acquire);
}

void IActor::Excute()
{
	do
	{
		const auto available = __claimStrategy.wait_until_published(__nextToRead, std::chrono::nanoseconds(30));
		if (available < __nextToRead)
		{
			SetStatus(WAITING);
			return;
		}
		//check equal?
		while (__nextToRead <= available)
		{
			Event_t e = __buffer[__nextToRead];
			__consumed.publish(__nextToRead + __buffer.size());

			_inerHandle(e);
			__nextToRead++;
		}

	} while (true);
}

void IActor::Post(Event_t event)
{
	const auto seq = __claimStrategy.claim_one();
	__buffer[seq] = event;
	__claimStrategy.publish(seq);
}

}